home *** CD-ROM | disk | FTP | other *** search
- static char sccs_id[] = "@(#)wlist.cc 1.1 2/15/94 10:38:13";
- /*+++
-
- : : wlist.cc
-
- PURPOSE : wlist member functions
-
- DATE : Sat Jan 29 19:15:47 EST 1994
-
- AUTHOR : W. Hatch
-
- PROJECT : WEH Software
-
- COMPANY : Coleman Research Corporation
- 9891 Broken Land Parkway
- Suite 200
- Columbia, Maryland 21045
- Phone (301)621-8600
- FAX (410)7210
- ---*/
- /*
- ------------------------------------------------------------------------
- MODIFICATIONS
- DATE PROGRAMMER DESCRIPTION
- ========================================================================
- 2-15-94 W. Hatch added functions ExchangePrevious(),
- ExchangeNext(), Maximum(), Minimum(), Sort(),
- Reverse(), Copy(), SetCompareData()
- */
-
- #include <stdio.h>
- #include <string.h>
- #include <wlist.h>
-
- //--------------------------------------------------------------------
- // constructor
- //--------------------------------------------------------------------
- wlist::wlist(){
- //------------------------------------------------------------
- // set size to zero, node pointers to null
- //------------------------------------------------------------
- size=0;
- first=(node *)0;
- last =(node *)0;
- current=(node *)0;
- name=new char[10];
- strcpy(name,"noname");
- CompareData = 0;
- PrintData = 0;
- }
- //--------------------------------------------------------------------
- // destructor
- //--------------------------------------------------------------------
- wlist::~wlist(){
- DeleteAll();
- delete [] name;
- }
- //--------------------------------------------------------------------
- // Size - return list size
- //--------------------------------------------------------------------
- int wlist::Size(){return size;}
-
- //--------------------------------------------------------------------
- // Name - access and assign list name
- //--------------------------------------------------------------------
- char *wlist::Name(){return name;}
-
- char *wlist::Name(char *s){
- if(s != (char *)0)
- {
- delete [] name;
- name = new char[strlen(s)+1];
- s[0]='\0';
- strcpy(name,s);
- }
- return name;
- }
-
-
-
- //--------------------------------------------------------------------
- // PrependData - add node to top of list
- //--------------------------------------------------------------------
- void *wlist::PrependData(void *v){
- //------------------------------------------------------------
- // create new node containing the given data
- //------------------------------------------------------------
- node *n = new node;
- n->NodeData(v);
- if(Size()==0)
- {
- //----------------------------------------------------
- // list empty, insert 1 node
- //----------------------------------------------------
- current=n;
- first = n;
- last = n;
- }
- else
- {
- //----------------------------------------------------
- // list not empty, insert 1 node, reset node pointers
- // to maintain doubly linked list connectivity
- //----------------------------------------------------
- node *ff = first;
-
- current=n;
- first=n;
-
- ff->PreviousNode(n);
- n->NextNode(ff);
- }
- //------------------------------------------------------------
- // increment node count
- //------------------------------------------------------------
- ++size;
- return v;
- }
- //--------------------------------------------------------------------
- // AppendData - add data to end of list
- //--------------------------------------------------------------------
- void *wlist::AppendData(void *v){
- //------------------------------------------------------------
- // create new node containing the given data
- //------------------------------------------------------------
- node *n = new node;
- n->NodeData(v);
- if(Size()==0)
- {
- //----------------------------------------------------
- // list empty, insert 1 node
- //----------------------------------------------------
- current=n;
- first = n;
- last = n;
- }
- else
- {
- //----------------------------------------------------
- // list not empty, insert 1 node, reset node pointers
- // to maintain doubly linked list connectivity
- //----------------------------------------------------
- node *ll = last;
- last=n;
- current = n;
- ll->NextNode(n);
- n->PreviousNode(ll);
- }
- //------------------------------------------------------------
- // increment node count
- //------------------------------------------------------------
- ++size;
- return v;
- }
- //--------------------------------------------------------------------
- // CurrentData - access and assign current data
- //--------------------------------------------------------------------
- void *wlist::CurrentData(){
- if(Size() > 0)
- //----------------------------------------------------
- // list not empty, return current node data
- //----------------------------------------------------
- return current->NodeData();
- else
- //----------------------------------------------------
- // list empty, return null
- //----------------------------------------------------
- return (void *)0;
- }
- void *wlist::CurrentData(void *v){
- if(Size() > 0)
- //----------------------------------------------------
- // list not empty, replace current node contents
- //----------------------------------------------------
- return current->NodeData(v);
- else
- {
- //----------------------------------------------------
- // list empty, append given data
- //----------------------------------------------------
- return AppendData(v);
- }
- }
- //--------------------------------------------------------------------
- // FirstData - access and assign first data
- //--------------------------------------------------------------------
- void *wlist::FirstData(){
- if(Size()==0)
- //----------------------------------------------------
- // list empty, return null
- //----------------------------------------------------
- return (void *)0;
- else
- {
- //----------------------------------------------------
- // list not empty, set current to first, return the data
- // contents of current node
- //----------------------------------------------------
- current=first;
- return first->NodeData();
- }
- }
- void *wlist::FirstData(void *v){
- if(Size()==0)
- {
- //----------------------------------------------------
- // list empty, append given data
- //----------------------------------------------------
- return AppendData(v);
- }
- else
- {
- //----------------------------------------------------
- // list not empty, set current to first, replace
- // data contents of first node.
- //----------------------------------------------------
- current=first;
- return first->NodeData(v);
- }
- }
-
-
- //--------------------------------------------------------------------
- // LastData - access and assign last data
- //--------------------------------------------------------------------
- void *wlist::LastData() {
- if(Size()==0)
- //----------------------------------------------------
- // list empty, return null
- //----------------------------------------------------
- return (void *)0;
- else
- {
- //----------------------------------------------------
- // list not empty, set cuttent to last node, return
- // last node contents
- //----------------------------------------------------
- current=last;
- return last->NodeData();
- }
- }
- void *wlist::LastData( void *v) {
- if(Size()==0)
- {
- //----------------------------------------------------
- // list empty, append given data
- //----------------------------------------------------
- return AppendData(v);
- }
- else
- {
- //----------------------------------------------------
- // list not empty, set current to last node, replace
- // data contents of last node with given data
- //----------------------------------------------------
- current=last;
- return last->NodeData(v);
- }
- }
- //--------------------------------------------------------------------
- // NextData - access and assign next data
- //--------------------------------------------------------------------
- void *wlist::NextData(){
- //------------------------------------------------------------
- // if list is empty, return null
- //------------------------------------------------------------
- if(Size()==0)
- {
- return (void *)0;
- }
- //------------------------------------------------------------
- // if current is last node, there is no next so return null
- //------------------------------------------------------------
- else if(current==last)
- {
- return (void *)0;
- }
- else
- //------------------------------------------------------------
- // set current to next node and return the data contents
- //------------------------------------------------------------
- {
- current=current->NextNode();
- return current->NodeData();
- }
- }
- void *wlist::NextData(void *v){
- //------------------------------------------------------------
- // if list is empty, append node containing the given data
- //------------------------------------------------------------
- if(Size()==0)
- {
- return AppendData(v);
- }
- //------------------------------------------------------------
- // if current is last node, append a node containing given data
- //------------------------------------------------------------
- else if(current==last)
- {
- return AppendData(v);
- }
- //------------------------------------------------------------
- // set current to next node and replace the node data
- // contents with the given data
- //------------------------------------------------------------
- else
- {
- current=current->NextNode();
- return current->NodeData(v);
- }
- }
- //--------------------------------------------------------------------
- // PreviousData - access and assign next data
- //--------------------------------------------------------------------
- void *wlist::PreviousData(){
- //------------------------------------------------------------
- // if list is empty, return null
- //------------------------------------------------------------
- if(Size()==0)
- {
- return (void *)0;
- }
- //------------------------------------------------------------
- // if current is first node, there is no previous so return null
- //------------------------------------------------------------
- else if(current==first)
- {
- return (void *)0;
- }
- else
- //------------------------------------------------------------
- // set current to previous node and return the data contents
- //------------------------------------------------------------
- {
- current=current->PreviousNode();
- return current->NodeData();
- }
- }
- void *wlist::PreviousData(void *v){
- //------------------------------------------------------------
- // if list is empty, append node containing the given data
- //------------------------------------------------------------
- if(Size()==0)
- {
- return AppendData(v);
- }
- //------------------------------------------------------------
- // if current is first node, preppend a node containing given data
- //------------------------------------------------------------
- else if(current==first)
- {
- return PrependData(v);
- }
- //------------------------------------------------------------
- // set current to previous node and replace the node data
- // contents with the given data
- //------------------------------------------------------------
- else
- {
- current=current->PreviousNode();
- return current->NodeData(v);
- }
- }
- //--------------------------------------------------------------------
- // PreInsert - insert data before current node, inserted node becomes
- // current node
- //--------------------------------------------------------------------
- void *wlist::PreInsert(void *v){
- if(Size()==0)
- return AppendData(v);
- else if(current == first)
- return PrependData(v);
- else
- {
- node *cc=current;
- node *pp=current->PreviousNode();
-
- //---------------------------------------------------------
- // create a new node and give it the data pointer
- // make new node the current node
- //---------------------------------------------------------
- node *dd=new node;
- dd->NodeData(v);
-
- current = dd;
-
- //---------------------------------------------------------
- // set pointers from current node to its next and
- // previous node
- //---------------------------------------------------------
- current->NextNode(cc);
- current->PreviousNode(pp);
-
- //---------------------------------------------------------
- // set pointers from next and previous nodes to the
- // current node
- //---------------------------------------------------------
- cc->PreviousNode(current);
- pp->NextNode(current);
-
- //---------------------------------------------------------
- // increment list size
- //---------------------------------------------------------
- ++size;
-
- return current->NodeData();
-
- }
- }
- //--------------------------------------------------------------------
- // PostInsert - insert data after current node, inserted node becomes
- // current node
- //--------------------------------------------------------------------
- void *wlist::PostInsert(void *v){
- if(Size()==0)
- return AppendData(v);
- else if(current == last)
- return AppendData(v);
- else
- {
- node *cc=current;
- node *nn=current->NextNode();
-
- //---------------------------------------------------------
- // create a new node and give it the data pointer
- // make new node the current node
- //---------------------------------------------------------
- node *dd=new node;
- dd->NodeData(v);
- current = dd;
-
- //---------------------------------------------------------
- // set pointers from current node to its next and
- // previous node
- //---------------------------------------------------------
- current->PreviousNode(cc);
- current->NextNode(nn);
-
- //---------------------------------------------------------
- // set pointers from next and previous nodes to the
- // current node
- //---------------------------------------------------------
- cc->NextNode(current);
- nn->PreviousNode(current);
-
- //---------------------------------------------------------
- // increment list size
- //---------------------------------------------------------
- ++size;
-
- return current->NodeData();
-
- }
- }
- //--------------------------------------------------------------------
- // DeleteCurrent() - delete current node from list
- //--------------------------------------------------------------------
- void *wlist::DeleteCurrent(){
- void *dd;
- if(Size()==0)
- return (void *)0;
- else if(Size()==1)
- {
- dd = CurrentData();
- delete current;
- current = (node *)0;
- first = (node *)0;
- last = (node *)0;
- --size;
- return dd;
- }
- else if(current == last)
- {
- dd = CurrentData();
- node *pp = current->PreviousNode();
- delete current;
- current = pp;
- last = pp;
- --size;
- current->NextNode((node *)0);
- return dd;
- }
- else if(current==first)
- {
- dd = CurrentData();
- node *nn=current->NextNode();
- delete current;
- current = nn;
- first = nn;
- current->PreviousNode((node *)0);
- --size;
- return dd;
- }
- else
- {
- dd=CurrentData();
- node *nn=current->NextNode();
- node *pp=current->PreviousNode();
- delete current;
- current=nn;
- current->PreviousNode(pp);
- pp->NextNode(nn);
- --size;
- return dd;
- }
- }
- //--------------------------------------------------------------------
- // DeleteAll - delete all list nodes, set size to zero - does NOT
- // delete the node contents and this is a potential source
- // of memory leakage
- //--------------------------------------------------------------------
- void wlist::DeleteAll(){
- int i;
- node *n;
- current = last;
- //------------------------------------------------------------
- // delete each node, no action taken on the data contents
- //------------------------------------------------------------
- for(i=0; i<Size(); i++)
- {
- n=current->PreviousNode();
- delete current;
- current = n;
- }
- size=0;
- }
- //--------------------------------------------------------------------
- // print - print the list contents, usually for test and debug
- //--------------------------------------------------------------------
- void wlist::print (){print(stdout);}
-
- void wlist::print(FILE *pf){
- void *d;
- fprintf(pf,"\tlist %s size %d\n",Name(),Size());
- fprintf(pf,"\tlist %s node %d data %x\n",Name(),0,FirstData());
- if(PrintData == 0)
- {
- return ;
- }
- PrintData(pf,FirstData());
- for(int i=1; i< Size(); i++)
- {
- d=NextData();
- fprintf(pf,"\tlist %s node %d data %x\n",Name(),i,d);
- if(d != (void *)0)
- PrintData(pf,d);
- else
- fprintf(pf,"\t\t(null)\n");
- }
- }
-
- void wlist::SetPrintData(void (*f)(FILE *pf,void *d)) {
- PrintData=f;
- }
- //----------------------------------------------------------------
- // SetCompareData - pass pointer to the data compare function to
- // be stored for future reference by Sort()
- //----------------------------------------------------------------
- void wlist::SetCompareData(int (*f)(void *a, void *b)){
- CompareData=f;
- }
- //----------------------------------------------------------------
- // Reverse - create a new list that is this list in reverse order
- //----------------------------------------------------------------
- wlist *wlist::Reverse(){
- int i;
- wlist *rev = new wlist;
-
- for(i=0; i< Size(); i++)
- {
- if(i==0)
- rev->NextData(LastData());
- else
- rev->NextData(PreviousData());
- }
- return rev;
- }
- //----------------------------------------------------------------
- // Sort - create a new list containing the data from this sorted
- // in ascending order. The current node in the new list will
- // be its last node and will contain the pointer to the data
- // that is considered the "largest" by the compare function.
- // This is a brute force implementation. If you want to efficiently
- // sort large lists then the sort algorithm needs more work.
- //----------------------------------------------------------------
- wlist *wlist::Sort(){
- void *idata;
- wlist *wl;
- wlist *xl;
- int i;
-
- if(CompareData == 0)
- {
- return (wlist *)0;
- }
- wl = Copy();
- xl = new wlist;
- for(i=0; i< Size(); i++)
- {
- idata=wl->Minimum();
- xl->NextData(idata);
- wl->DeleteCurrent();
- }
- delete wl;
- return xl;
- }
- //----------------------------------------------------------------
- // ExchangePrevious() - exchange data between current and previous
- // list nodes; return pointer to new current data
- //----------------------------------------------------------------
- void *wlist::ExchangePrevious(){
- void *cur;
- void *prev;
-
- // if list is empty or current is first node, return null
- if(Size()<= 0 || current==first)
- {
- return (void *)0;
- }
- cur = CurrentData();
- prev= PreviousData();
- NextData(prev);
- PreviousData(cur);
- return NextData();
- }
-
- //----------------------------------------------------------------
- // ExchangeNext() - exchange data between current and next list
- // nodes; return pointer to new current data
- //----------------------------------------------------------------
- void *wlist::ExchangeNext(){
- void *cur;
- void *nx;
-
- // if list is empty or current is last node, return null
- if(Size()<= 0 || current==last)
- {
- return (void *)0;
- }
- cur = CurrentData();
- nx= NextData();
- PreviousData(nx);
- NextData(cur);
- return PreviousData();
- }
- //----------------------------------------------------------------
- // Maximum() - return maximum data; current node is the node
- // containing the maximum
- //----------------------------------------------------------------
- void *wlist::Maximum(){
- //----------------------------------------------------------------
- // assure that CompareData() has been assigned
- //----------------------------------------------------------------
- if(CompareData == 0)
- {
- return (void *)0;
- }
- //----------------------------------------------------------------
- // handle the cases of zero and 1 list element
- //----------------------------------------------------------------
- if(Size() == 0)
- {
- return (void *)0;
- }
- if(Size()==1)
- {
- return FirstData();
- }
- int i;
- void *mx = FirstData();
- void *cur;
- //----------------------------------------------------------------
- // find the maximum
- //----------------------------------------------------------------
- for(i=0; i<(Size()-1);i++)
- {
- cur=NextData();
- if(CompareData(cur,mx) > 0)
- mx=cur;
- }
- //----------------------------------------------------------------
- // set the current node to that containing the maximum
- //----------------------------------------------------------------
- for(i=0; i< Size(); i++)
- {
- if(i==0)
- cur=FirstData();
- else
- cur=NextData();
- if(CompareData(cur,mx)==0)
- break;
- }
- return mx;
- }
- //----------------------------------------------------------------
- // Minimum() - return minimum data; current node is the node
- // containing the minimum
- //----------------------------------------------------------------
- void *wlist::Minimum(){
- //----------------------------------------------------------------
- // assure that CompareData() has been assigned
- //----------------------------------------------------------------
- if(CompareData == 0)
- {
- return (void *)0;
- }
- //----------------------------------------------------------------
- // handle the cases of zero and 1 list element
- //----------------------------------------------------------------
- if(Size() == 0)
- {
- return (void *)0;
- }
- if(Size()==1)
- {
- return FirstData();
- }
- int i;
- void *mx = FirstData();
- void *cur = (void *)0;
- //----------------------------------------------------------------
- // find the minimum
- //----------------------------------------------------------------
- for(i=0; i<(Size()-1);i++)
- {
- cur=NextData();
- if(CompareData(cur,mx) < 0)
- mx=cur;
- }
- //----------------------------------------------------------------
- // set the current node to that containing the minimum
- //----------------------------------------------------------------
- for(i=0; i< Size(); i++)
- {
- if(i==0)
- cur=FirstData();
- else
- cur=NextData();
- if(CompareData(cur,mx)==0)
- break;
- }
- return mx;
- }
- //----------------------------------------------------------------
- // Copy - create a copy of this; a new wlist is created. Each
- // node of the new list contains the same data pointer as
- // the corresponding node of this. No attempt is made to
- // copy the contents of the data structure pointed to
- // at each node. (This is a level 1 copy.)
- //----------------------------------------------------------------
- wlist *wlist::Copy(){
- wlist *wl = new wlist;
- int i;
- for(i=0; i<Size(); i++)
- {
- if(i==0)
- {
- wl->FirstData(FirstData());
- }
- else
- {
- wl->NextData(NextData());
- }
- }
- wl->PrintData=PrintData;
- wl->CompareData=CompareData;
- return wl;
- }
-
-